#include "stdafx.h"

void demograph :: init()
{
    bar_ratio = 1.f;
    cout << "bar_ratio " << bar_ratio << endl;
    deaths_total = 0;
    deaths_this_year = 0;
    births_total = 0;
    births_this_year = 0;

    pop_max = 100;
	run_sim = true;
	FOR(AGE_MAX)
    {
        pop.push_back(indiv());
        pop.back().age = i;
    }
    pop_total = pop.size();
}
void demograph :: simulation_step() // equivalent to 1 year
{
    births_this_year = reproducing_people = 0;
    //repr.clear();

    //for(auto a = population.begin(); a != population.end(); ++a)
    float birth_rate; // = births_this_year / persons_in_age
    current_size = pop.size();
    FOR(current_size)
    {
        if(pop[i].age == 0xff)
            continue;
        // add one yea
        pop[i].age ++;

        // deaths
        if(pop[i].age > AGE_MAX)
        {
            pop[i].age = 0xff;
            dead.push(i);
            deaths_total ++;
            deaths_this_year++;
            pop_total--;
        }

		if(pop[i].age >= AGE_REPRODUCE_MIN
            && pop[i].age < AGE_REPRODUCE_MAX)
                repr.push(i);
    }
    size_t u = repr.size();
    FOR(u)
    {
		if(pop_total < pop_max)
		{
			pop[dead.back()].age = 0;
            pop[i].kids++;
			dead.pop();
            pop_total ++;
            births_total++;
            births_this_year++;
		}
		else
		{
			cout << "too many people\n";
			run_sim = false;
			return;
		}
    }
}
void demograph :: simulation_step2()
{
    births_this_year =
    reproducing_people =
    deaths_this_year =
    gen_heirs = 0;

    current_size = pop.size();
    FOR(current_size)
    //for(auto ind = pop.begin(); ind != pop.end(); ++ ind)
    {
        if(pop[i].age == 0xff)
            continue;
        pop[i].age ++;

        if(pop[i].age >= AGE_REPRODUCE_MIN
            && pop[i].age < AGE_REPRODUCE_MAX)
        {
            gen_heirs += pop[i].kids;
            repr.push(i);
        }
    }
    while(!repr.empty())
    {
        //if(float(pop[i].kids) > CHILD_PER_PERSON)
        //    continue;
        if(pop.size() >= pop_max)
        {
            cout << "too many people\n";
            run_sim = false;
            return;
        }
        if(float(gen_heirs) / float(reproducing_people) > CHILD_PER_PERSON)
            return; // birth rate reached

        births_total++;
        births_this_year++;
        gen_heirs++; // this is important !

        size_t a;
        if(dead.empty())
        {
            pop.push_back(indiv());
            a = pop.size() - 1;
        }
        else
        {
            a = dead.back();
            dead.pop();
        }
        pop[a].age = 0;
        pop[a].kids = 0;
        repr.pop();
    }
}
/*
The goals of the simulation are as follow
- Births per couple must not exceed 2.5, so 1.25 per person.
- only 1 birth per year
- only people between 20 and 35 can have children

we loop the population
if the person is between 20 and 35, we add one children

*/

void demograph::init_bars()
{
    text = sf::Text("",sf::Font::getDefaultFont(),FONT_SIZE);
    FOR(AGE_MAX)
        bars[i].setPosition(BAR_WIDTH*i, BAR_H_MAX);

    FOR2(0, AGE_REPRODUCE_MIN)
        bars[i].setFillColor(sf::Color::Cyan);
    FOR2(AGE_REPRODUCE_MIN, AGE_REPRODUCE_MAX)
        bars[i].setFillColor(sf::Color::Green);
    FOR2(AGE_REPRODUCE_MAX,AGE_MAX)
        bars[i].setFillColor(sf::Color::Yellow);
}
void demograph::update_bars()
{
    FOR(AGE_MAX)
        age_group[i] = 0;
    
    FOR(pop_max)
    {
        if(pop[i].age == 0xff)
            continue;
        age_group[pop[i].age]++;
    }

    ostringstream oss;
    FOR(AGE_MAX)
    {
        oss << age_group[i] << " ";
        if((i+1)%10 == 0)
            oss << "\n";
        bars[i].setSize(sf::Vector2f(age_group[i],0));
    }
    oss << "\n" << births_this_year << " " << births_total << "\n";
    FOR(pop_max)
        if(pop[i].age != 0xff)
            cout << size_t(pop[i].age) << " ";
    cout << "\n";
    text.setString(oss.str());
}
